﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CloudStorageLight.Web.Tests
{
    public static class SharePointSubScenarioUtil
    {
        private static string baseUrl = AppUtil.GetAppConfigValue("baseSharePointUrl");
        public static IWebDriver CreateWebDriver()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.AddUserProfilePreference("download.default_directory", Environment.CurrentDirectory);
            chromeOptions.AddUserProfilePreference("intl.accept_languages", "ja");
            chromeOptions.AddUserProfilePreference("disable-popup-blocking", "true");
            chromeOptions.AddArguments("--disable-extensions");
            return new ChromeDriver(chromeOptions);
        }

        public static string GetUrl(string path, string account = null)
        {
            if (string.IsNullOrEmpty(account))
            {
                return baseUrl + path;
            }
            else
            {
                return baseUrl + "(" + account + ")/" + path;
            }
        }

        public static IWebElement GetFolderOrFileElement(IWebDriver driver, string linkText)
        {
            for (int i = 0; i < 30; i++)
            {
                try
                {
                    var eles = driver.FindElements(By.XPath("//span[@class='list-title item-name']"));
                    var ele = eles.FirstOrDefault(x => x.Text == linkText); ;
                    if (ele != null) return ele;
                    eles = driver.FindElements(By.XPath("//span[@class='item-name']"));
                    ele = eles.FirstOrDefault(x => x.Text == linkText); ;
                    if (ele != null) return ele;
                }
                catch (Exception)
                {
                }
                Thread.Sleep(1000);
            }
            throw new Exception(linkText + " element was not found");
        }
        public static IWebElement CheckFileElement(IWebDriver driver, string linkText)
        {
            var target = GetFolderOrFileElement(driver, linkText);
            target = target.FindElement(By.XPath("../../../..//input"));
            target.Click();
            return target;
        }


        public static bool Exists(IWebDriver driver, string linkText)
        {
            for (int i = 0; i < 30; i++)
            {
                var eles = driver.FindElements(By.XPath("//span[@class='list-title item-name']"));
                var ele = eles.FirstOrDefault(x => x.Text == linkText); ;
                if (ele != null) return true;
                eles = driver.FindElements(By.XPath("//span[@class='item-name']"));
                ele = eles.FirstOrDefault(x => x.Text == linkText); ;
                if (ele != null) return true;
                Thread.Sleep(1000);
            }
            return false;
        }

        public static void UploadFile(IWebDriver driver, string filePath)
        {
            var javascriptDriver = driver as IJavaScriptExecutor;
            // append input to HTML to add file path
            //javascriptDriver.ExecuteScript("$(\"<form method='post' id='uploadtemp' enctype = 'multipart/form-data' ><input type='file' id='tempfile' name='tempfile'  /><input id='current' name='current' type='hidden' value='/Demo/' /></form>\").appendTo('body');");
            javascriptDriver.ExecuteScript("$(\"<form method='post' id='uploadtemp' enctype = 'multipart/form-data' ><input type='file' id='tempfile' name='tempfile'  /></form>\").appendTo('body');");

            driver.FindElement(By.Id("tempfile")).SendKeys(filePath);
            driver.FindElement(By.Id("uploadtemp")).Submit();

        }

        public static void DeleteFile(IWebDriver driver, string file)
        {
            ClickContextMenu(driver, file, "compremove-context-command");
            driver.SwitchTo().Alert().Accept();
        }

        public static void RemoveFile(IWebDriver driver, string file)
        {
            ClickContextMenu(driver, file, "remove-context-command");
            driver.SwitchTo().Alert().Accept();
        }

        public static void ClickContextMenu(IWebDriver driver, string file, string cmd)
        {
            var javascriptDriver = driver as IJavaScriptExecutor;
            if (!Exists(driver, file)) return;
            var ele = GetFolderOrFileElement(driver, file);
            ele.FindElements(By.XPath("../../../..//div"))[2].Click();
            TryClick(driver, By.ClassName(cmd));
        }

        public static void DeleteFolder(IWebDriver driver, string folder)
        {
            var javascriptDriver = driver as IJavaScriptExecutor;
            if (!Exists(driver, folder)) return;
            var ele = GetFolderOrFileElement(driver, folder);
            ele.Click();
            ClickMenuCommand(driver, "removefolder-command");
            driver.SwitchTo().Alert().Accept();
        }

        public static IWebElement TryFind(IWebDriver driver, By target, int retryCount = 30)
        {
            for (int i = 0; i < retryCount; i++)
            {
                try
                {
                    var ele = driver.FindElement(target);
                    if (ele != null)
                    {
                        return ele;
                    }
                }
                catch
                {

                }
                Thread.Sleep(1000);
            }
            return null;
        }

        public static bool TryClick(IWebDriver driver, By target, int retryCount = 30)
        {
            for (int i = 0; i < retryCount; i++)
            {
                try
                {
                    var ele = driver.FindElement(target);
                    if (ele != null)
                    {
                        ele.Click();
                        return true;
                    }
                }
                catch
                {

                }
                Thread.Sleep(1000);
            }
            return false;
        }

        public static bool WaitBusy(IWebDriver driver, int retryCount = 30)
        {
            for (int i = 0; i < retryCount; i++)
            {
                try
                {
                    var ele = driver.FindElement(By.Id("prog-cancel"));
                    if (ele == null || !ele.Displayed)
                    {
                        return true;
                    }
                }
                catch
                {
                    return true;
                }
                Thread.Sleep(1000);
            }
            return false;
        }

        public static void ClickMenuCommand(IWebDriver driver, string cmd)
        {
            if (!TryClick(driver, By.LinkText("操作")))
            {
                TryClick(driver, By.LinkText("Operation"));
            }
            TryClick(driver, By.Id(cmd));
        }

        public static void ClearDownloadFile(string path)
        {
            if (File.Exists(path)) File.Delete(path);
        }

        public static bool CheckDownloadFile(string path)
        {
            for (int i = 0; i < 10; i++)
            {
                if (File.Exists(path)) return true;
                Thread.Sleep(1000);
            }
            throw new Exception(path + " download file was not found");
        }

        public static IWebDriver CreateDriverAndLogin(string account, bool admin = false)
        {
            IWebDriver driver = CreateWebDriver();
            var user = AppUtil.GetAppConfigValue("SharePointUser");
            var password = AppUtil.GetAppConfigValue("SharePointPassword");
            return Login(account, user, password, admin, driver);
        }

        public static IWebDriver Login(string account, string user, string password, bool admin, IWebDriver driver)
        {
            if (AppUtil.GetAppConfigValue("SharePointSite").StartsWith("http://localhost"))
            {
                Navigate(driver, "Account/Login");
                IWebElement element = driver.FindElement(By.Id("cloudAccount"));
                element.SendKeys(account);
                element = driver.FindElement(By.Id("email"));
                element.SendKeys(user);
                element = driver.FindElement(By.Id("password"));
                element.SendKeys(password);
                element.Submit();
            }
            else
            {
                driver.Navigate().GoToUrl("https://login.microsoftonline.com/");
                IWebElement element = driver.FindElement(By.Id("cred_userid_inputtext"));
                element.SendKeys(user);
                element = driver.FindElement(By.Id("cred_password_inputtext"));
                element.SendKeys(password);
                element.Submit();
            }
            return driver;

        }

        public static void Navigate(IWebDriver driver, string path, string account = null)
        {
            driver.Navigate().GoToUrl(GetUrl(path, account));
        }

        public static void SetUserEmailConfirmed(string account, string username)
        {
            var connectionString = AppUtil.GetAppConfigValue("TestBlobConnectionString");
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            var tableClient = storageAccount.CreateCloudTableClient();
            var table = tableClient.GetTableReference(account + "AspNetUsers");

            var list = table.ExecuteQuery(new TableQuery());
            var user = list.Where(x => x.Properties["UserName"].StringValue == username).FirstOrDefault();
            if (user != null)
            {
                user.Properties["EmailConfirmed"] = new EntityProperty(true);

                TableBatchOperation batchOperation = new TableBatchOperation();
                table.Execute(TableOperation.Replace(user));
            }

        }


        public static string GetFileTransferGuid(string account, string title)
        {
            var connectionString = AppUtil.GetAppConfigValue("TestBlobConnectionString");
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            var tableClient = storageAccount.CreateCloudTableClient();
            var table = tableClient.GetTableReference(account + "FileTransferWorktask");

            var list = table.ExecuteQuery(new TableQuery());
            var workItem = list.Where(x => x.Properties["Title"].StringValue == title).FirstOrDefault();
            if (workItem != null)
            {
                return workItem.RowKey;
            }
            return null;
        }
    }

}
